<?php

namespace app\api\controller;

use app\common\controller\Api;
use app\common\model\Delivery;
use think\Config;
use think\Db;
use think\Exception;
use think\Model;
use think\Validate;
use app\common\model\Goods;
use app\common\model\OrderProducts;
use app\common\model\Address;

/**
 * 首页接口
 */
class Order extends Api
{
    protected $noNeedLogin = [];
    protected $noNeedRight = ['*'];

    protected $model = null;

    public function __construct()
    {
        parent::__construct();
        $this->model = new \app\common\model\Order;
    }

    /**
     * 确认收货
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function confirm()
    {
        $order_sn = $this->request->request('order_sn');

        $where = [
            'order_sn'  => $order_sn,
            'user_id'   => $this->auth->id,
            'state'     => 1,
            'pay_state' => 1,
            'ship_state' => 1,
        ];
        $order = $this->model
            ->where($where)
            ->find();

        if (!$order) $this->error('i18n:160');
        if ($order['expiretime']) {
			$this->error('i18n:159');
		}

        //确认收货时间
        $confirm_time = time();

        //订单数据
        $orderParam = [
            'ship_state' => 2, //发货状态 0=待发货 1=已发货 2=已收货
            'state' => 2, //订单状态 1=正常 2=完成 3=取消
            'confirm_time'  => $confirm_time,
        ];

        //发货单数据
        $deliveryParam = [
            'confirm_time'  => $confirm_time,
            'status'        => 3, //状态 1=准备发货 2=已发货 3=已确认 4=其他
        ];

        $deliveryModel = new Delivery();

        Db::startTrans();
        try {
            $map = [
                'order_sn'  => $order_sn,
            ];
            //更新订单状态
            $this->model->save($orderParam,$map);
            //更新发货单状态
            $deliveryModel->save($deliveryParam,$map);
            Db::commit();
        }catch (Exception $e){
            Db::rollback();
            $msg = $e->getMessage();
            $this->error($msg);
        }

        $data = [
            'order_sn'  => $order_sn,
        ];
        $this->success('i18n:158',$data);
    }


    /**
     * 提交订单接口
     * 创建主订单和货品订单详情
     * TODO 立即购买 暂时不考虑购物车流程 不考虑多规格
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function create()
    {
        $address_id = $this->request->post('address_id');
        $num = $this->request->post('num',1);
        $products_id = $this->request->request('products_id');
        //TODO 传参规格

        //校验数据 BEGIN
        $param = [
            'address_id'    => $address_id,
            'num'           => $num,
            'products_id'  => $products_id,
        ];

        $rule = [
            'address_id'    => 'require',
            'products_id'   => 'require',
            'num'           => 'require|egt:1'
        ];

        $msg = [
            'address_id.require'    => 'address_id not empty',
            'products_id.require'   => 'products_id not empty',
            'num.egt'               => 'Must be greater than 0',
        ];

        $validate = new Validate($rule, $msg);
        $result = $validate->check($param);
        if (!$result) {
            $this->error($validate->getError());
        }
        //校验数据 END
        $map = [
            'market_switch'     => 1, //上架
            'id'                => $products_id,
        ];

        $data = model('app\common\model\Products')
            ->field('id,goods_id,price,is_defalut,sn,stock,spes_desc,image')
            ->with(['goods'=>function($query){
                $query->field('id,name,price,stock,params,is_nomal_virtual,bn');
            }])
            ->where($map)
            ->find();

        /*$data = model('app\common\model\Goods')
            ->field('id,name,price,stock,params,is_nomal_virtual,bn')
            ->with(['products'=>function($query){
                $query->field('id,goods_id,price,is_defalut,sn,stock,spes_desc,image');
            }])
            ->where($map)
            ->find();*/

        if (!$data){
            $this->error('The product has been taken off the shelf');
        }

        //TODO 后台获取运费 然后生成订单
        if (Config::get('site.freight_fee') > 0){
            $freight = Config::get('site.freight_fee');
        }else{
            //免运费
            $freight = 0;
        }

        $goods = $data['goods'];
        $products = $data;

        //虚拟商品运费为0
        if ($goods['is_nomal_virtual'] == 2) $freight = 0;

        //生成主订单号
        $order_sn = get_sn(1);
        //整理order_products 数据


        //订单商品货品详情
        $orderProductsData = [
            'order_sn'  => $order_sn,
            'goods_id'  => $goods['id'],
            'products_id'  => $products['id'],
            'bn'        => $goods['bn'], //商品编码
            'sn'        => $products['sn'], //货品编码
            'name'      => $goods['name'], //商品名称
            'spes_desc' => $products['spes_desc'], //货品规格
            'price'     => $products['price'], //货品单价
            'num'       => $num, //数量
            'amount'    => bcmul($products['price'],$num,2), //奖品价格乘以数量
            'image'     => $products['image'],
            'is_nomal_virtual'  => $goods['is_nomal_virtual'], //是否虚拟商品
        ];

        //生成订单 获取订单id 更新prize_draw 的 订单编号 更新商品冻结库存
        $orderProductsModel = new OrderProducts();
        $addressModel = new Address();
        $goodsModel = new Goods();

        //TODO 根据address_id 获取收货地址具体信息 防止发生改动
        $address_where = [
            'id'        => $address_id,
            'user_id'   => $this->auth->id,
        ];
        $address = $addressModel->where($address_where)->find();
        if (!$address) {
            $this->error('i18n:176');
        }

        //应付款 订单总额 奖品总价格 + 运费
        $order_amount = bcadd($orderProductsData['amount'],$freight,2);
        //整理订单数据
        $orderParam = [
            'order_sn'      => $order_sn,
            'user_id'       => $this->auth->id,
            'ip'            => $this->request->ip(0,true),
            'address_id'    => $address_id,    //收货地址id
            'order_amount'  => $order_amount,  //应付款 订单总额 奖品总价格 + 运费
            'prize_amount'  => 0, //奖品总价格 TODO 商品立即购买 prize_amount=0
            'freight_fee'   => $freight, //邮费运费
            'state'         => 1, //订单状态 1=正常 2=完成 3=取消
            'pay_state'     => 0, //支付状态 0=待付款 1=已付款
            'ship_state'    => 0, //发货状态 0=待发货 1=已发货 3=已收货
            'payment'       => 0, //已付款金额（实付金额）
            'ship_name'     => $address['name'],
            'ship_mobile'   => $address['mobile'],
            'ship_area'     => $address['area'],
            'ship_detail'   => $address['detail'],
        ];
        /*echo '<pre>';
        var_dump($orderProductsData);exit;*/

        //应付款 为0 则state 支付状态 直接为1
        if ($order_amount == 0) {
            $orderParam['pay_state'] = 1;         //支付状态
            $orderParam['payment_time'] = time(); //支付时间
        }
        //$this->success('',$orderParam);
        //如果应付款 = 0，state 直接为支付完成状态

        Db::startTrans();
        try {
            //生成订单
            $this->model->save($orderParam);
            //生成orderproducts
            $orderProductsModel->save($orderProductsData);
            //提交订单增加冻结库存
            $ret = $goodsModel->changeStock($products['id'],'order',$num);

            Db::commit();
        }catch (Exception $e){
            Db::rollback();
            $this->error($e->getMessage());
        }

        $this->success('',[
            'order_sn' => $order_sn,
            'money' => $orderParam['order_amount'], //应付款 订单总额 奖品总价格 + 运费
            'state' => $orderParam['state'], //订单状态 1=正常 2=完成 3=取消
            'pay_state' => $orderParam['pay_state'], //支付状态 0=待付款 1=已付款
        ]);
    }

    public function creates()
    {
        $address_id = $this->request->post('address_id');

        $num_arr = $this->request->post('num/a');
        $products_id_arr = $this->request->request('products_id/a');
        //TODO 传参规格

        //校验数据 BEGIN
        $param = [
            'address_id'    => $address_id,
        ];

        $rule = [
            'address_id'    => 'require',
        ];

        $msg = [
            'address_id.require'    => 'address_id not empty',
        ];

        $validate = new Validate($rule, $msg);
        $result = $validate->check($param);
        if (!$result) {
            $this->error($validate->getError());
        }

        $address_where = [
            'id'        => $address_id,
            'user_id'   => $this->auth->id,
        ];
        $addressModel = new Address();
        $address = $addressModel->where($address_where)->find();
        if (!$address) {
            $this->error('Address Not find');
        }

        //生成主订单号
        $order_sn = get_sn(1);
        $order_amount = 0;

        foreach ($products_id_arr as $k => $v){
            $products_id = $v;
            $num = $num_arr[$k];

            //校验数据 END
            $map = [
                'market_switch'     => 1, //上架
                'id'                => $products_id,
            ];

            $data = model('app\common\model\Products')
                ->field('id,goods_id,price,is_defalut,sn,stock,spes_desc,image')
                ->with(['goods'=>function($query){
                    $query->field('id,name,price,stock,params,is_nomal_virtual,bn');
                }])
                ->where($map)
                ->find();

            if (!$data){
                $this->error('The product has been taken off the shelf');
            }

            //免运费
            $freight = 0;

            $goods = $data['goods'];
            $products = $data;

            //整理order_products 数据
            //订单商品货品详情
            $orderProductsData[] = [
                'order_sn'  => $order_sn,
                'goods_id'  => $goods['id'],
                'products_id'  => $products['id'],
                'bn'        => $goods['bn'], //商品编码
                'sn'        => $products['sn'], //货品编码
                'name'      => $goods['name'], //商品名称
                'spes_desc' => $products['spes_desc'], //货品规格
                'price'     => $products['price'], //货品单价
                'num'       => $num, //数量
                'amount'    => bcmul($products['price'],$num,2), //奖品价格乘以数量
                'image'     => $products['image'],
                'is_nomal_virtual'  => $goods['is_nomal_virtual'], //是否虚拟商品
            ];

            //生成订单 获取订单id 更新prize_draw 的 订单编号 更新商品冻结库存
            $orderProductsModel = new OrderProducts();
            $goodsModel = new Goods();

            //应付款 订单总额 奖品总价格 + 运费
            $order_amount += bcadd(bcmul($products['price'],$num,2),$freight,2);


        }

        //整理订单数据
        $orderParam = [
            'order_sn'      => $order_sn,
            'user_id'       => $this->auth->id,
            'ip'            => $this->request->ip(0,true),
            'address_id'    => $address_id,    //收货地址id
            'order_amount'  => $order_amount,  //应付款 订单总额 奖品总价格 + 运费
            'prize_amount'  => 0, //奖品总价格 TODO 商品立即购买 prize_amount=0
            'freight_fee'   => $freight, //邮费运费
            'state'         => 1, //订单状态 1=正常 2=完成 3=取消
            'pay_state'     => 0, //支付状态 0=待付款 1=已付款
            'ship_state'    => 0, //发货状态 0=待发货 1=已发货 3=已收货
            'payment'       => 0, //已付款金额（实付金额）
            'ship_name'     => $address['name'],
            'ship_mobile'   => $address['mobile'],
            'ship_area'     => $address['area'],
            'ship_detail'   => $address['detail'],
        ];

        //应付款 为0 则state 支付状态 直接为1
        if ($order_amount == 0) {
            $orderParam['pay_state'] = 1;         //支付状态
            $orderParam['payment_time'] = time(); //支付时间
        }

        Db::startTrans();
        try {
            //生成订单
            $this->model->save($orderParam);
            //生成orderproducts
            $orderProductsModel->saveAll($orderProductsData);
            //提交订单增加冻结库存
            foreach ($orderProductsData as $k => $order){
                $ret = $goodsModel->changeStock($order['products_id'],'order',$order['num']);

            }

            Db::commit();
        }catch (Exception $e){
            Db::rollback();
            $this->error($e->getMessage());
        }

        $this->success('',[
            'order_sn' => $order_sn,
            'money' => $orderParam['order_amount'], //应付款 订单总额 奖品总价格 + 运费
            'state' => $orderParam['state'], //订单状态 1=正常 2=完成 3=取消
            'pay_state' => $orderParam['pay_state'], //支付状态 0=待付款 1=已付款
        ]);
    }

    public function index()
    {
        $map = [
            'user_id'   => $this->auth->id,
        ];

        //TODO 临时展示
        $data = $this->model
            ->field('id,order_sn,state,pay_state,ship_state,order_amount,freight_fee')
            ->with(['orderproducts'=>function($query){
                $query->withfield('order_sn,name,price,image');
            }])
            ->where($map)
            ->order('createtime desc')
            ->paginate(20);

        //不执行 返回sql
        //->fetchSql(true)->select();
        //echo $data;exit;

        $statusDict = [
            0 => 'i18n:11',
            1 => 'i18n:161',
            2 => 'i18n:51',
        ];

        //处理data
        foreach ($data as $k=>$v){
            $data[$k]['orderproducts']['image'] = getRealUrl($v['orderproducts']['image']);

            //返回订单状态
            $tips = '';
            if ($v['state'] == 1){
                if ($v['pay_state'] == 1){
                    if ($v['ship_state'] == 1){
                        $tips = 'Shipped'; //已发货
                    }elseif ($v['ship_state'] == 2){
                        $tips = 'Received'; //已收货
                    }else {
                        $tips = 'To be shipped'; //待发货
                    }
                }else {
                    $tips = 'To be paid'; //待支付
                }
            }elseif ($v['state'] == 2){
                $tips = 'Completed'; //已完成
            }elseif ($v['state'] == 3){
                $tips = 'Cancelled'; //已取消
            }

            $data[$k]['tips']  = $tips;
        }

        //$data['status'] = $status;
        $this->success('i18n:62',$data);
    }

}
